import streamlit as st
import os
from datetime import datetime
import pandas as pd
import re
from besins_selenium_downloaders.file_manager import *
from besins_selenium_downloaders.streamlit_tools import (
    get_browser_name_for_site_name,
    configure_page_navigation,
)
from besins_selenium_downloaders.config import *
from besins_selenium_downloaders.network import *
from bs4 import BeautifulSoup
import glob

class App:
    def __init__(self):
        self.setup_page_config()
        configure_page_navigation("app")
        self.df = None
        self.df_markdown = None
        self.selected_folder = None
        self.main()

    def setup_page_config(self):
        # Configure the page with a wide layout and custom title/icon
        st.set_page_config(
            page_title="🤖 Besins Automation Dashboard",
            page_icon="🤖",
            layout="wide",
            initial_sidebar_state="expanded",
        )

        # Load and inject CSS
        common_css_path = os.path.join(os.path.dirname(__file__), "css", "common.css")
        with open(common_css_path) as f:
            st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)

        css_path = os.path.join(os.path.dirname(__file__), "css", "app.css")
        with open(css_path) as f:
            st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)

        # Main header with enhanced emoji
        st.markdown(
            '<h1 class="common-title">📊 Besins Automation Dashboard</h1>',
            unsafe_allow_html=True,
        )

    def display_info_section(self):
        # Add an information section with additional emojis
        st.markdown(
            '<div class="section-header">ℹ️ Help & Instructions</div>',
            unsafe_allow_html=True,
        )
        with st.expander("🔍 How to use this dashboard", expanded=False):
            st.markdown(
                """
                ### Welcome to the Besins Automation Dashboard! 🎉
                
                This dashboard helps you monitor and manage automated data collection processes.
                
                **Key Features:**
                - 📅 **View automation results by date**
                - 📸 **Access screenshots of the automation process**
                - 📥 **Download collected data files**
                - 🔄 **Run automation for specific sites**
                - ⚠️ **Monitor errors and warnings**
                
                **Getting Started:**
                1. 📂 **Select a date folder** from the dropdown below
                2. 📈 **Review the metrics and data table**
                3. 🔗 **Click on file links** to view screenshots or download data
                4. 🔁 **Use the rerun button** to retry failed automations
                """
            )

    def format_files(self, row, column):
        files = row[column]
        site_name = row["SiteName"]
        if not files:
            return "❌ None"
        return ", ".join([f"[📄 {file[len(site_name) + 1:]}]({file})" for file in files])

    def format_dataframe(self):
        self.df_markdown = self.df.copy()

        # Store original site names before adding tooltips
        original_site_names = self.df_markdown["SiteName"].copy()

        # Count screenshots and make them clickable using the original SiteName
        self.df_markdown["Screenshots"] = self.df_markdown.apply(
            lambda row: (
                f'<a href="screenshots_viewer?date={self.selected_folder}&site={original_site_names[row.name]}">'
                f'{len(row["Screenshots"]) if row["Screenshots"] else 0}</a>'
                if row["Screenshots"] else "0"
            ),
            axis=1,
        )

        # Count downloaded files and make them clickable using the original SiteName
        self.df_markdown["Downloaded"] = self.df_markdown.apply(
            lambda row: (
                f'<a href="xlsx_viewer?date={self.selected_folder}&site={original_site_names[row.name]}">'
                f'{len(row["Downloaded"]) if row["Downloaded"] else 0}</a>'
                if row["Downloaded"] else "0"
            ),
            axis=1,
        )

        # Make errors clickable with link to log viewer using the original SiteName
        self.df_markdown["Errors"] = self.df_markdown.apply(
            lambda row: f'<a href="log_viewer?date={self.selected_folder}&site={original_site_names[row.name]}">{row["Errors"]}</a>',
            axis=1,
        )

        # Add link to rerun page using the original SiteName
        self.df_markdown["Rerun"] = self.df_markdown.apply(
            lambda row: f'<a href="run_one_website?site={original_site_names[row.name]}" class="metric-link">▶️ Rerun</a>',
            axis=1,
        )

    def display_table(self):
        """Display the results table with dynamic adjustments for columns, search, and sorting."""
        st.markdown(
            '<div class="section-header">📋 Detailed Results</div>',
            unsafe_allow_html=True,
        )

        col1, col2 = st.columns(2)
        with col1:
            search = st.text_input(
                "🔍 Search", placeholder="Filter by SiteName, TaskID, or URL..."
            )
        with col2:
            sort_by = st.selectbox("🔄 Sort by", ["SiteName", "TaskID"], index=0)

        show_columns = st.multiselect(
            "👁️ Show Columns",
            [
                "SiteName",
                "TaskID",
                "Login",
                "Screenshots",
                "Errors",
                "Downloaded",
                "URL",
                "Browser",
                "Rerun",
            ],
            default=[
                "SiteName",
                "Login",
                "Screenshots",
                "Downloaded",
                "Errors",
                "Rerun",
            ],
        )
        if not show_columns:
            show_columns = ["SiteName", "Login", "Screenshots", "Errors", "Downloaded", "Rerun"]

        # Prepare data for display
        sites_data = []
        for idx, row in self.df_markdown.iterrows():
            site_info = {
                "SiteName": row["SiteName"],
                "TaskID": row["TaskID"],
                "Login": row["Login"],
                "Screenshots": row["Screenshots"],
                "Errors": row["Errors"],
                "Downloaded": row["Downloaded"],
                "URL": row["URL"],
                "Browser": get_browser_name_for_site_name(row["SiteName"]),
                "Rerun": row["Rerun"],
            }
            # Get original values for tooltip
            original_task_id = self.df.iloc[idx]["TaskID"]
            original_url = self.df.iloc[idx]["URL"]
            site_info["tooltip"] = (
                f"🆔 Task ID: {original_task_id} | 🌐 URL: {original_url}"
            )
            sites_data.append(site_info)

        # Apply filtering
        if search:
            search_lower = search.lower()
            sites_data = [
                site
                for site in sites_data
                if search_lower in site["SiteName"].lower()
                or search_lower in site["TaskID"].lower()
                or search_lower in site["URL"].lower()
            ]

        # Apply sorting
        if sort_by == "SiteName":
            sites_data.sort(key=lambda x: BeautifulSoup(x["SiteName"], "html.parser").get_text())
        else:
            sites_data.sort(key=lambda x: x[sort_by])

        # Create a styled table using HTML
        table_html = """
        <div class="table-content">
            <table class="table table-striped">
                <thead>
                    <tr>
        """

        # Add selected columns to header
        for col in show_columns:
            table_html += f"<th>{col}</th>"

        table_html += "</tr></thead><tbody>"

        # Add data rows with tooltips
        for site in sites_data:
            table_html += f'<tr title="{site["tooltip"]}">'
            for col in show_columns:
                value = site[col]
                if col == "URL":
                    original_url = value
                    display_url = (
                        original_url[:50] + "..."
                        if len(original_url) > 50
                        else original_url
                    )
                    value = f'<a href="{original_url}" target="_blank" title="{original_url}" class="website-url">{display_url}</a>'
                table_html += f"<td>{value}</td>"
            table_html += "</tr>"

        table_html += "</tbody></table></div>"

        # Display the HTML table with horizontal scrolling
        st.markdown(table_html, unsafe_allow_html=True)

    def display_metrics(self):
        st.markdown(
            '<div class="section-header">📈 Summary Metrics</div>', unsafe_allow_html=True
        )

        # Calculate metrics
        total_tasks = get_number_of_tasks()
        successful_logins = len(self.df[self.df["Login"] == "✅"])
        success_rate = (
            (successful_logins / len(self.df)) * 100 if len(self.df) > 0 else 0
        )
        total_errors = self.df["Errors"].sum()
        total_downloaded_files = (
            self.df["Downloaded"]
            .apply(lambda x: len(x) if isinstance(x, list) else 0)
            .sum()
        )

        # Calculate remaining sites
        remaining_sites = total_tasks - len(self.df)

        # Display each metric separately with enhanced emojis
        metric1 = f"""
        <div class="metric-container">
            <div class="metric-label">📊 Total Sites</div>
            <div class="metric-value">{len(self.df)}<span class="metric-total">/ {total_tasks}</span></div>
        </div>
        """

        metric2 = f"""
        <div class="metric-container">
            <div class="metric-label">⏳ Remaining Sites</div>
            <div class="metric-value-remaining">
                <a href="run_remaining_websites" class="metric-link-remaining">
                    {remaining_sites}
                </a>
            </div>
        </div>
        """

        metric3 = f"""
        <div class="metric-container">
            <div class="metric-label">✅ Successful Logins</div>
            <div class="metric-value metric-value-success">
                {successful_logins}<span class="metric-total"> ({success_rate:.1f}%)</span>
            </div>
        </div>
        """

        metric4 = f"""
        <div class="metric-container">
            <div class="metric-label">📥 Downloaded Files</div>
            <div class="metric-value metric-download">{total_downloaded_files}</div>  
        </div>
        """

        metric5 = f"""
        <div class="metric-container">
            <div class="metric-label">⚠️ Total Errors</div>
            <div class="metric-value metric-value-error">{total_errors}</div>  
        </div>
        """

        # Combine metrics in a container
        metrics_container = f"""
        <div class="metrics-row">
            {metric1.strip()}
            {metric2.strip()}
            {metric3.strip()}
            {metric4.strip()}
            {metric5.strip()}
        </div>
        """

        # Display the metrics container
        st.markdown(metrics_container, unsafe_allow_html=True)

    def main(self):
        # Create a container for the main content
        with st.container():
            # Handle folder selection
            date_folders = get_list_date_folders()
            if not date_folders:
                st.error("🚫 No date folders found in the current directory.")
                return

            # Sort folders by date (newest first)
            date_folders.sort(reverse=True)

            # Create folder selection dropdown
            st.markdown(
                '<div class="section-header">📅 Select Date Folder</div>',
                unsafe_allow_html=True,
            )
            self.selected_folder = st.selectbox(
                "📂 Select a date folder to view automation results",
                options=date_folders,
                help="Choose a date folder to view automation results",
            )

            if self.selected_folder:
                # Check if the selected folder contains relevant files
                relevant_files = [f for f in os.listdir(self.selected_folder) if f.endswith(('.png', '.xlsx', '.xls'))]
                if not relevant_files:
                    html = """
                        <div class="attention-message">
                            <h4>🚨 Attention Required!</h4>
                            <p>
                                The selected folder is empty. To perform automation tasks for today, please click the button below to run all websites.
                            </p>
                            <a href="run_all_websites" class="run-button-red">
                                <span class="button-icon">🚀</span> Click to Run All Websites
                            </a>
                        </div>
                    """
                    st.markdown(html, unsafe_allow_html=True)
                else:
                    # Load and process data
                    pass
                    # try:
                    #     self.df = get_date_folder_analysis_as_dataframe(self.selected_folder)
                    #     if self.df is not None and not self.df.empty:
                    #         # Format and display data
                    #         self.format_dataframe()

                    #         # Display metrics at the top
                    #         self.display_metrics()

                    #         # Display the detailed results table
                    #         self.display_table()
                    #     else:
                    #         st.warning("⚠️ No data found in the selected folder.")
                    # except Exception as e:
                    #     st.error(f"❌ Error processing folder: {str(e)}")
                    #     st.exception(e)

        self.display_actions()
        self.display_info_section()

    def display_actions(self):
        with st.container():
            st.markdown(
                '<div class="section-header">🔧 Actions</div>',
                unsafe_allow_html=True,
            )

            col1, col2 = st.columns(2)
            with col1:
                if st.button(
                    "💰 Get TwoCaptcha Balance",
                    help="Click this button to check your current balance on your 2Captcha account. "
                         "This will send a request to the 2Captcha API to retrieve your balance. "
                ):
                    with st.spinner("🔄 Getting TwoCaptcha Balance..."):
                        from besins_selenium_downloaders import get_twocaptcha_balance

                        try:
                            success, info = get_twocaptcha_balance()
                            if success:
                                st.success(f"✅ {info}")
                            else:
                                st.error(f"❌ {info}")
                        except Exception as e:
                            st.error(f"❌ Error getting TwoCaptcha balance: {str(e)}")
                            st.exception(e)
            with col2:
                if st.button(
                    "🧹 Remove Empty Date Folders",
                    help="Click this button to remove any empty date folders from your project directory. "
                         "The application will scan for folders that match the date format (YYYY-MM-DD) "
                         "and check if they contain any relevant files (e.g., .png, .xlsx, .xls). "
                         "If a folder is found to be empty, it will be deleted. "
                ):
                    with st.spinner("🗑️ Removing empty date folders..."):
                        success, info = remove_empty_date_folders()
                        if success:
                            st.success(f"✅ {info}")
                        else:
                            st.error(f"❌ {info}")

            col1, col2 = st.columns(2)
            with col1:
                if st.button(
                    "🧹 Remove Ongoing Downloads in Tmp Folder",
                    help="Click to remove all incomplete downloads (.part or .crdownload files) from your tmp downloads directory."
                ):
                    with st.spinner("🗑️ Removing ongoing downloads..."):
                        try:
                            download_dir = load_configuration().get("directories", {}).get("browser_downloads_directory", "./Downloads-tmp")
                            ongoing_downloads = glob.glob(os.path.join(download_dir, '*.part')) + \
                                             glob.glob(os.path.join(download_dir, '*.crdownload'))
                            count = len(ongoing_downloads)
                            for file in ongoing_downloads:
                                os.remove(file)
                            if count > 0:
                                st.success(f"✅ Successfully removed {count} ongoing download{'s' if count != 1 else ''}")
                            else:
                                st.info("ℹ️ No ongoing downloads found")
                        except Exception as e:
                            st.error(f"❌ Error removing ongoing downloads: {str(e)}")
                            
            with col2:
                if st.button(
                    "🗑️ Clear Tmp Downloads Folder",
                    help="Click to remove all files from your tmp downloads directory. Use with caution!"
                ):
                    with st.spinner("🗑️ Removing all downloaded files..."):
                        try:
                            download_dir = load_configuration().get("directories", {}).get("browser_downloads_directory", "./Downloads-tmp")
                            all_files = glob.glob(os.path.join(download_dir, '*'))
                            count = len(all_files)
                            for file in all_files:
                                if os.path.isfile(file):  
                                    os.remove(file)
                            if count > 0:
                                st.success(f"✅ Successfully removed {count} file{'s' if count != 1 else ''}")
                            else:
                                st.info("ℹ️ Tmp Downloads folder is already empty")
                        except Exception as e:
                            st.error(f"❌ Error clearing downloads folder: {str(e)}")

            col1, col2 = st.columns(2)
            with col1:
                if st.button(
                    "🔄 Install Selenium Firefox Driver",
                    help="Install Selenium Firefox Driver",
                ):
                    with st.spinner("🔧 Installing Selenium Firefox Driver..."):
                        success, info, firefox_driver_path = install_firefox_driver()
                        if success == 1:
                            st.success(f"✅ {info}")
                            st.info(f"🔍 Firefox Driver Path: {firefox_driver_path}")
                        elif success == 2:
                            st.error(f"❌ {info}")
                            st.error(f"🔍 Firefox Driver Path: {firefox_driver_path}")
            with col2:
                if st.button(
                    "🔄 Install Selenium Chrome Driver",
                    help="Install Selenium Chrome Driver",
                ):
                    with st.spinner("🔧 Installing Selenium Chrome Driver..."):
                        success, info, chrome_driver_path = install_chrome_driver()
                        if success == 1:
                            st.success(f"✅ {info}")
                            st.info(f"🔍 Chrome Driver Path: {chrome_driver_path}")
                        elif success == 2:
                            st.error(f"❌ {info}")
                            st.error(f"🔍 Chrome Driver Path: {chrome_driver_path}")

            col1, col2 = st.columns(2)
            with col1:
                if st.button(
                    "🔍 Check Baidu.com Access (Firefox)",
                    help="Click to verify access to Baidu.com using the Firefox browser.",
                ):
                    with st.spinner("🔄 Verifying access to `Baidu.com` with Selenium (Firefox)..."):
                        success = verify_baidu_firefox_accessibility()
                        if success:
                            st.success("✅ Access to Baidu.com with Firefox browser verified successfully.")
                        else:
                            st.error("❌ Failed to access Baidu.com with Firefox. Please check your connection or settings.")
            with col2:
                if st.button(
                    "🔍 Check Google.com Access (Chrome)",
                    help="Click to verify access to Google.com using the Chrome browser.",
                ):
                    with st.spinner("🔄 Verifying access to `Google.com` with Selenium (Chrome)..."):
                        success = verify_google_chrome_accessibility()
                        if success:
                            st.success("✅ Access to Google.com with Chrome browser verified successfully.")
                        else:
                            st.error("❌ Failed to access Google.com with Chrome. Please check your connection or settings.")


if __name__ == "__main__":
    App()
